using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.IO;
using System.Windows.Forms;
using System.Xml.Serialization;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;

namespace ReportMaintenanceUtility
{
	/// <summary>
	/// Describes a field returned by an associated DataSet query
	/// </summary>
	public class Field : GenericBase<Field>
	{
		#region PRIVATE MEMBER(S)
		private FieldType	_seed			= null;
		private string		_name			= string.Empty;
		private string		_type			= string.Empty;
		private string		_dataFieldName	= string.Empty;
		private string		_value			= string.Empty;
		#endregion

		#region PUBLIC PROPERTIES

		/// <summary>
		/// 
		/// </summary>
		public string Name
		{
			get { return this._name; }
		}

		/// <summary>
		/// 
		/// </summary>
		public string Type
		{
			get { return this._type; }
		}

		/// <summary>
		/// 
		/// </summary>
		public string DataFieldName
		{
			get { return this._dataFieldName; }
		}

		/// <summary>
		/// 
		/// </summary>
		public string Value
		{
			get { return this._value; }
		}

		#endregion

		#region CONSTRUCTOR(S)

		/// <summary>
		/// 
		/// </summary>
		/// <param name="fld"></param>
		private Field(Field fld)
		{
			if (fld == null)
			{
				throw new ArgumentNullException();
			}
			else
			{
				this._name = fld._name;
				this._seed = (FieldType)fld.CreateSeedCopy();
				this.Initialize();
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="ft"></param>
		public Field(FieldType ft)
		{
			if (ft == null)
			{
				throw new ArgumentNullException();
			}
			else
			{
				this._name = ft.Name;
				this._seed = ft;
				this.Initialize();
			}
		}
		protected override void Initialize()
		{
			for (int i = 0; i < this._seed.ItemsElementName.Length; i++)
			{
				switch (this._seed.ItemsElementName[i])
				{
					case ItemsChoiceType1.Item:
						try
						{
							this._type = ((XmlElement)this._seed.Items[i]).InnerText;
						}
						catch (InvalidCastException ex)
						{
							Debug.Print(ex.Message);
						}
						break;

					case ItemsChoiceType1.DataField:
						if (this._seed.Items[i] != null && this._seed.Items[i] is string)
						{
							this._dataFieldName = (string)this._seed.Items[i];
						}
						break;

					case ItemsChoiceType1.Value:
						if (this._seed.Items[i] != null && this._seed.Items[i] is string)
						{
							this._value = (string)this._seed.Items[i];
						}
						break;
				}
			}
		}
		#endregion

		#region INTERFACE IMPLEMENTATION(S)

		/// <summary>
		/// 
		/// </summary>
		/// <param name="other"></param>
		/// <returns></returns>
		public override bool EqualTo(Field other)
		{
			if (other == null)
			{
				return false;
			}
			else
			{
				return
					this._name.Equals(other._name, StringComparison.CurrentCultureIgnoreCase) &&
					this._type.Equals(other._type, StringComparison.CurrentCultureIgnoreCase) &&
					this._dataFieldName.Equals(other._dataFieldName, StringComparison.CurrentCultureIgnoreCase) &&
					this._value.Equals(other._value, StringComparison.CurrentCultureIgnoreCase);
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		public override List<ChangeLog> SaveState()
		{
			List<ChangeLog> log = new List<ChangeLog>();

			//todo: add SaveState() code here...

			this.ClearState();
			return log;
		}

		/// <summary>
		/// 
		/// </summary>
		public override void RestoreState()
		{
			if (this._copy != null)
			{
				this._name = ((Field)this._copy).Name;
				this._type = ((Field)this._copy).Type;
			}
			this.ClearState();
		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		public override Field CreateDeepCopy()
		{
			return new Field(this);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		public FieldType GetSeedObject()
		{
			return this._seed;
		}

		#endregion

		public override object CreateSeedCopy()
		{
			FieldType ft = new FieldType();
			ft.Name = this._name;

			List<ItemsChoiceType1> elements = new List<ItemsChoiceType1>();
			List<object> items = new List<object>();

			for (int i = 0; i < this._seed.ItemsElementName.Length; i++)
			{
				switch (this._seed.ItemsElementName[i])
				{
					case ItemsChoiceType1.Item:
						try
						{
							XmlElement xe = (XmlElement)(((XmlElement)this._seed.Items[i]).Clone());
							items.Add(xe);
							elements.Add(ItemsChoiceType1.Item);
						}
						catch (InvalidCastException ex)
						{
							Debug.Print(ex.Message);
						}
						break;

					case ItemsChoiceType1.DataField:
						items.Add(this._dataFieldName);
						elements.Add(ItemsChoiceType1.DataField);
						break;

					case ItemsChoiceType1.Value:
						items.Add(this._value);
						elements.Add(ItemsChoiceType1.Value);
						break;
				}
			}

			ft.ItemsElementName = elements.ToArray();
			ft.Items = items.ToArray();

			return ft;
		}
	}
}